﻿using Apewer;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Apewer.Internals
{

    /// <summary>注册表。</summary>
    static class RegHelper
    {

        /// <summary>用户登录后的启动项。</summary>
        const string RunKey = @"Software\Microsoft\Windows\CurrentVersion\Run";

        /// <summary>HKEY_CURRENT_USER</summary>
        /// <remarks>当前用户的信息。</remarks>
        static RegistryKey CurrentUser { get => Registry.CurrentUser; }

        /// <summary>HKEY_LOCAL_MACHINE</summary>
        /// <remarks>系统信息，对所有用户生效，设置需要管理员权限。</remarks>
        static RegistryKey LocalMachine { get => Registry.LocalMachine; }

        static RegistryKey OpenSubKey(RegistryKey root, string key, bool write = false)
        {
            var segs = key.Split('\\', '/');
            var queue = new Queue<string>(segs);
            var rkey = root;
            var check = write ? RegistryKeyPermissionCheck.ReadWriteSubTree : RegistryKeyPermissionCheck.ReadSubTree;
            while (queue.Count > 0)
            {
                var name = queue.Dequeue();
                var sub = rkey.OpenSubKey(name, check);
                if (sub == null)
                {
                    if (!write) return null;
                    rkey = rkey.CreateSubKey(name);
                }
                else
                {
                    rkey = sub;
                }
            }
            return rkey;
        }

        /// <summary>获取字符串。</summary>
        /// <param name="root">注册表存储区。</param>
        /// <param name="key">路径。</param>
        /// <param name="name">名称。</param>
        /// <returns>字符串的值。获取失败时返回 NULL 值。</returns>
        static string Get(RegistryKey root, string key, string name)
        {
            try
            {
                var rkey = OpenSubKey(root, key, false);
                if (rkey == null) return null;

                var names = rkey.GetValueNames().ToList();
                if (names.Contains(name))
                {
                    var obj = rkey.GetValue(name, null);
                    var str = obj as string;
                    return str;
                }
            }
            catch { }
            return null;
        }

        /// <summary>设置字符串，指定 value 为 NULL 可删除该值。</summary>
        /// <param name="root">注册表存储区。</param>
        /// <param name="key">路径。</param>
        /// <param name="name">名称。</param>
        /// <param name="value">值。</param>
        /// <returns>错误信息。设置成功时返回 NULL 值。</returns>
        static string Set(RegistryKey root, string key, string name, string value)
        {
            try
            {
                var rkey = OpenSubKey(root, key, true);
                if (rkey == null) return "无法打开子键。";

                var apps = rkey.GetValueNames();
                if (string.IsNullOrEmpty(value)) rkey.DeleteValue(name, true);
                else rkey.SetValue(name, value, RegistryValueKind.String);
                return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>已启用自动启动。</summary>
        public static bool AutoRun
        {
            get
            {
                var exePath = Application.ExecutablePath;
                var exeName = Path.GetFileNameWithoutExtension(exePath);
                return Get(CurrentUser, RunKey, exeName) == exePath;
            }
            set
            {
                var exePath = Application.ExecutablePath;
                var exeName = Path.GetFileNameWithoutExtension(exePath);
                Set(CurrentUser, RunKey, exeName, value ? exePath : null);
            }
        }

    }

}
